local LinkedList = require("LinkedList")

local LRUCache = {}
LRUCache.__cname = "util.LRUCache"
LRUCache.__index = LRUCache

function LRUCache.new(capacity)
    local obj = {}
    setmetatable(obj, LRUCache)
    obj:ctor(capacity)
    return obj
end

function LRUCache:ctor(capacity)
    self.capacity = capacity
    self.cache = {}
    self.list = LinkedList.new()
end

function LRUCache:Put(key, value)
    local node = self.cache[key]
    if nil == node then --缓存中没有
        node = self.list:AddFirst({k=key, v=value})
        self.cache[key] = node
        --如果超过了容量, 移除链表尾部元素
        if self.list:GetCount() > self.capacity then
            local nodeValue = self.list:RemoveLast():GetValue()
            self.cache[nodeValue.k] = nil
            --print(">capacity", nodeValue.k, nodeValue.v)
        end
    else --缓存中已经有了
        node:GetValue().v = value
        --最近被访问了, 放到链表最前面
        self.list:MoveToFirst(node)
    end
end

function LRUCache:Get(key)
    local node = self.cache[key]
    if nil == node then return nil end --缓存中没有
    self.list:MoveToFirst(node)
    return node:GetValue()
end

function LRUCache:Remove(key)
    local node = self.cache[key]
    if nil == node then return end --缓存中没有
    self.cache[key] = nil
    self.list:MoveToFirst(node)
end

function LRUCache:Clear()
    self.cache = {}
    self.list:Clear()
end

return LRUCache
